package com.tduck.cloud.account.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.tduck.cloud.account.entity.OrgEntity;
import com.tduck.cloud.account.entity.dto.OrgEntityDTO;
import com.tduck.cloud.account.entity.enums.TreeNodeWithSelfEnum;
import com.tduck.cloud.account.mapper.OrgMapper;
import com.tduck.cloud.account.service.OrgService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * org服务impl
 *
 * @author Guard Baby
 * @date 2023/04/18
 */
@Slf4j
@Service("orgService")
@RequiredArgsConstructor
public class OrgServiceImpl extends ServiceImpl<OrgMapper, OrgEntity> implements OrgService {

    /**
     * 根id
     */
    private static final Long ROOT_ID = 2308297821294849L;
    /**
     * 是否有子节点 0-没有 1-有
     */
    private static final Integer IS_END = 0;

    /**
     * 根据父节点查询查询子节点树
     *
     * @param parent 父
     * @return {@link List}<{@link OrgEntityDTO}>
     */
    @Override
    public List<OrgEntityDTO> queryAllChildNode(Long parent) {
        return queryAllChildNode(parent, TreeNodeWithSelfEnum.WITH_SELF);
    }

    /**
     * 查询所有子节点
     *
     * @param parent   父
     * @param withSelf 与自我
     * @return {@link List}<{@link OrgEntityDTO}>
     */
    @Override
    public List<OrgEntityDTO> queryAllChildNode(Long parent, TreeNodeWithSelfEnum withSelf) {
        if (Objects.isNull(parent)) {
            parent = ROOT_ID;
        }
        if (Objects.isNull(withSelf)) {
            withSelf = TreeNodeWithSelfEnum.WITH_SELF;
        }
        if (Objects.equals(parent, ROOT_ID)) {
            QueryWrapper<OrgEntity> queryWrapper = new QueryWrapper<>();
            if (TreeNodeWithSelfEnum.WITHOUT_SELF.equals(withSelf)) {
                queryWrapper.ne("id", ROOT_ID);
            }
            List<OrgEntity> list = this.baseMapper.selectList(queryWrapper);
            List<OrgEntityDTO> dtos = BeanUtil.copyToList(list, OrgEntityDTO.class);
            return buildTree(dtos, parent);
        }
        return buildTree(BeanUtil.copyToList(queryAllChildNode(parent, Lists.newArrayList(), withSelf.getValue()), OrgEntityDTO.class), parent);
    }

    @Override
    public List<OrgEntityDTO> queryExpandAllChildNode(Long parent, TreeNodeWithSelfEnum withSelf) {

        return BeanUtil.copyToList(queryAllChildNode(parent, Lists.newArrayList(), withSelf.getValue()), OrgEntityDTO.class);
    }

    /**
     * 查询所有子节点
     *
     * @param parent   父
     * @param list     列表
     * @param withSelf 与自我
     * @return {@link List}<{@link OrgEntity}>
     */
    private List<OrgEntity> queryAllChildNode(Long parent, List<OrgEntity> list, int withSelf) {
        OrgEntity orgEntity = this.baseMapper.selectById(parent);
        if (withSelf == 1) {
            list.add(orgEntity);
        }
        if (Objects.equals(orgEntity.getIsEnd(), IS_END)) {
            QueryWrapper<OrgEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("parent", orgEntity.getId());
            List<OrgEntity> children = this.baseMapper.selectList(queryWrapper);
            if (CollUtil.isNotEmpty(children)) {
                list.addAll(children);
                for (OrgEntity org : children) {
                    queryAllChildNode(org.getId(), list, TreeNodeWithSelfEnum.WITHOUT_SELF.getValue());
                }
            }
        }
        return list;
    }


    /**
     * 构建树
     *
     * @param dataList 数据列表
     * @param parentId 父id
     * @return {@link List}<{@link OrgEntityDTO}>
     */
    private List<OrgEntityDTO> buildTree(List<OrgEntityDTO> dataList, Long parentId) {
        List<OrgEntityDTO> result = new ArrayList<>();
        dataList.forEach(t -> {
            if (Objects.equals(parentId, t.getParent())) {
                t.setChildren(buildTree(dataList, t.getId()));
                result.add(t);
            }
        });
        //todo-lx 没有包含id 为parentId自身元素
        return result;
    }
}
